#include "BasicRect2D.h"
#include "../GameLib.h"
#include "../../OpenGL.h"
#include "Line2D.h"

BasicRect2D::BasicRect2D(){
    width=0;
    height=0;
}
BasicRect2D::BasicRect2D(Point2D &pt, double width, double height){
    set(pt,width,height);
}
BasicRect2D::BasicRect2D(double x, double y, double width, double height){
    set(x,y,width,height);
}
BasicRect2D::BasicRect2D(Point2D &pt, Point2D &ptB){
    set(pt,ptB);
}
BasicRect2D& BasicRect2D::set(Point2D &pt, double width, double height){
    position=pt;
    if (width<0){this->width=0;}
    else{this->width=width;}
    if (height<0){this->height=0;}
    else{this->height=height;}
    return *this;
}
BasicRect2D& BasicRect2D::set(double x, double y, double width, double height){
    set(Point2D().set(x,y),width,height);
    return *this;
}
BasicRect2D& BasicRect2D::set(Point2D &pt, Point2D &ptB){
    ptB-=pt;
    set(pt,ptB.getX(),ptB.getY());
    return *this;
}
BasicRect2D::~BasicRect2D(){}

//With other shapes
BasicRect2D& BasicRect2D::closestPoint(Point2D &pt, Point2D &from){
    unsigned char mask;
    //0000YYXX
    //##01=left
    //##00=center (x)
    //##10=right
    //01##=up
    //00##=center (y)
    //10##=down
    if (pt.getX()<position.getX()){mask=1;}
    else if (pt.getX()<position.getX()+width){mask=0;}
    else{mask=2;}
    if (pt.getY()<position.getY()){mask|=4;}
    else if (pt.getY()>=position.getY()+height){mask|=8;}
    
    from=position;//this was at the start of every case
    Point2D t,tpt;
    
    switch (mask)
    {
    case 0x0000://center
        {
            double winner;
            winner = from.distance(pt);
            
            tpt.set(width,0);
            t.copy(position).add(tpt);
            if (t.distance(pt)<winner){from=t;}
            
            tpt.set(width,height);
            t.copy(position).add(tpt);
            if (t.distance(pt)<winner){from=t;}
            
            tpt.set(0,height);
            t.copy(position).add(tpt);
            if (t.distance(pt)<winner){from=t;}
        }
        break;
    case 1://0b0001://left
        from.setY(pt);
        break;
    case 2://0b0010://right
        tpt.set(width,0);
        from+=tpt;
        from.setY(pt);
        break;
    case 4://0b0100://up=
        from.setX(pt);
        break;
    case 8://0x1000://down
        tpt.set(0,height);
        from+=tpt;
        from.setX(pt);
        break;
    case 5://0b0101://left-up
        break;
    case 6://0b0110://up-right
        tpt.set(width,0);
        from+=tpt;
        break;
    case 9://0b1001://down-left
        tpt.set(0,height);
        from+=tpt;
        break;
    case 10://0b1010://down-right
        tpt.set(width,height);
        from+=tpt;
        break;
    default:break;
    }
    //my point is a point in the rectange that represents the closest point to pt
    return *this;
}
BasicRect2D& BasicRect2D::closestPoint(Line2D &line, Point2D &from, Point2D &to){
    //some other day
    return *this;
}
bool BasicRect2D::captures(Point2D &pt){
    if (pt.getX()<position.getX()){return false;}
    if (pt.getX()>position.getX()+width){return false;}
    if (pt.getY()<position.getY()){return false;}
    if (pt.getY()>position.getY()+height){return false;}
    return true;
}
bool BasicRect2D::captures(Line2D &line){
    return false;
}
void BasicRect2D::drawSolid(double depth){
    glBegin(GL_QUADS);
    glVertex3f((float)position.getX(),(float)position.getY(),(float)depth);
    glVertex3f((float)(position.getX()+width),(float)position.getY(),(float)depth);
    glVertex3f((float)(position.getX()+width),(float)(position.getY()+height),(float)depth);
    glVertex3f((float)position.getX(),(float)(position.getY()+height),(float)depth);
    glEnd();
}
void BasicRect2D::drawSolid_color(double depth, int hexColor){
    gameLib.setColor(hexColor);
    drawSolid(depth);
}
void BasicRect2D::drawPerim(double depth){
    glBegin(GL_LINES);
    glVertex3f((float)position.getX(),(float)position.getY(),(float)depth);
    glVertex3f((float)(position.getX()+width),(float)position.getY(),(float)depth);
    
    glVertex3f((float)(position.getX()+width),(float)position.getY(),(float)depth);
    glVertex3f((float)(position.getX()+width),(float)(position.getY()+height),(float)depth);
    
    glVertex3f((float)(position.getX()+width),(float)(position.getY()+height),(float)depth);
    glVertex3f((float)position.getX(),(float)(position.getY()+height),(float)depth);
    
    glVertex3f((float)position.getX(),(float)(position.getY()+height),(float)depth);
    glVertex3f((float)position.getX(),(float)position.getY(),(float)depth);
    glEnd();
}
void BasicRect2D::drawPerim_width(double depth, double dWidth){
    double oldLineWidth;
    oldLineWidth = gameLib.getLineWidth();
    gameLib.setLineWidth(dWidth);
    drawPerim(depth);
    gameLib.setLineWidth(oldLineWidth);
}
void BasicRect2D::drawPerim_color(double depth, int hexColor){
    float c[4];
    gameLib.getColorA(c);
    gameLib.setColor(hexColor);
    drawPerim(depth);
    gameLib.setColorA(c);
}
void BasicRect2D::drawPerim_widthColor(double depth, double dWidth, int hexColor){
    float c[4];
    gameLib.getColorA(c);
    gameLib.setColor(hexColor);
    drawPerim_width(depth,dWidth);
    gameLib.setColorA(c);
}